package com.lgCore.serverProcesser;/**
 * Created by by on 2020/11/13 10:35
 */

import com.google.protobuf.ByteString;
import com.lgCore.common.LocalSession;
import com.lgCore.factory.FilterFactory;
import com.lgCore.factory.InvokRpcServiceFactory;
import com.lgCore.protoModel.ProtoMsg;
import com.lgCore.server.invok.invokBean.InvokRpcMethod;
import com.lgCore.util.ByteObjUtil;
import com.lgCore.util.ExceptionUtil;
import com.lgCore.util.ProtoByteUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * invok异步执行
 *
 * @program: sxreader_rpc
 * @author: ligang
 * @create: 2020-11-13 10:35
 */
public class ServiceInvokCallable implements Callable<ProtoMsg.Message> {
    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceInvokCallable.class);
    private ProtoMsg.Message message;
    private LocalSession session;

    public ServiceInvokCallable(ProtoMsg.Message message, LocalSession localSession) {
        this.message = message;
        this.session = localSession;
    }

    @Override
    public ProtoMsg.Message call() throws Exception {
        ProtoMsg.Message.Builder responseMsg = ProtoMsg.Message.newBuilder();

        /********************处理接受的数据（测试）start******************/
//        ProtoMsg.RpcResponse.Builder rpcResponse = ProtoMsg.RpcResponse.newBuilder();
//        rpcResponse.setClientId(message.getRpcRequest().getClientId());
//        rpcResponse.setRequestId(message.getRpcRequest().getRequestId());
//        rpcResponse.setIsSucess(true);
//        List<Object> objects = JSONArray.parseArray(message.getRpcRequest().getRequestObjects(), Object.class);
//        rpcResponse.setResponse(JSON.toJSONString(objects.get(0)));
//        rpcResponse.setType(ProtoMsg.HeadType.RPC_RESPONSE);
//        responseMsg.setRpcResponse(rpcResponse);
//        //发送给客户端消息
//        session.getChannel().writeAndFlush(responseMsg.build());

        /********************处理接受的数据（测试）end******************/
        //收到客户端的请求
        Date date = new Date();
        ProtoMsg.RpcRequest rpcRequest = message.getRpcRequest();
        //组装invok调用参数
//            CommonRpcRequest commonRpcRequest = askMsg.getParams().getCommonRpcRequest();
        InvokRpcMethod invokRpcMethod = new InvokRpcMethod();
        invokRpcMethod.setMethod(rpcRequest.getMethodName());
        invokRpcMethod.setServicePath(rpcRequest.getServiceName());
//        List<Object> objectList = JSONObject.parseArray(rpcRequest.getRequestObjects(), Object.class);
        Object object =null;
        try{
            object = ByteObjUtil.bytesToObject(rpcRequest.getRequestObjects().toByteArray());
        }catch (Exception e){
            e.printStackTrace();
        }
        Object[] objectList = (Object[]) object;
//        List<Object> objectList = (List<Object>) object;
        invokRpcMethod.setParamDatas(objectList);


        //方法入参参数
        Object paramTypeObject =null;
        try{
            paramTypeObject = ByteObjUtil.bytesToObject(rpcRequest.getArgTypes().toByteArray());
        }catch (Exception e){
            e.printStackTrace();
        }
        Class<?>[] paramTypes = (Class<?>[]) paramTypeObject;
        invokRpcMethod.setParamTypes(paramTypes);
        invokRpcMethod = InvokRpcServiceFactory.getCommonRpcRouteService().getInvokRpcMethod(invokRpcMethod);
        ProtoMsg.RpcResponse.Builder rpcResponse = ProtoMsg.RpcResponse.newBuilder();
        rpcResponse.setClientId(rpcRequest.getClientId());
        rpcResponse.setRequestId(rpcRequest.getRequestId());

        rpcResponse.setType(ProtoMsg.HeadType.RPC_RESPONSE);
        responseMsg.setRpcResponse(rpcResponse);
        //发送给客户端消息
//        System.out.println(new Date().getTime()-date.getTime());
//        session.getChannel().writeAndFlush(ProtoByteUtil.protoToByte(responseMsg));
        try {
            //调用
            Object obj = null;
            try {
                // TODO: 2021/4/12 这里处理 filter调用过滤器 doBeforeRequest方法
                FilterFactory.getRpcFilter().doBeforeRequest(invokRpcMethod.getMethod(),invokRpcMethod.getParamTypes(),invokRpcMethod.getParamDatas());

                obj = InvokRpcServiceFactory.getCommonRpcRouteService().methodInvoke(invokRpcMethod);
//              LOGGER.info("接口响应时间："+(new Date().getTime()-date.getTime()));
//                rpcResponse.setResponse(JSON.toJSONString(obj));

                // TODO: 2021/4/12 这里处理 filter 拦截器服务端后处理 doAfterRequest方法
                FilterFactory.getRpcFilter().doAfterRequest(obj);


                rpcResponse.setResponse(ByteString.copyFrom(ByteObjUtil.objToBytes(obj)));
                rpcResponse.setIsSucess(true);
            } catch (Exception e) {
                String errorMsg = ExceptionUtil.ExceptionDetailAll(e);
                rpcResponse.setIsSucess(false);
                rpcResponse.setException(errorMsg);
                LOGGER.info("接口调用失败：" + errorMsg);
                e.printStackTrace();
            }
        } catch (Exception e) {
//            e.printStackTrace();
            String errorMsg = ExceptionUtil.ExceptionDetailAll(e);
            rpcResponse.setIsSucess(false);
            rpcResponse.setException(errorMsg);
        }
        responseMsg.setRpcResponse(rpcResponse);
        //发送给客户端消息
        session.getChannel().writeAndFlush(ProtoByteUtil.protoToByte(responseMsg));
        return responseMsg.build();
    }
}
